﻿using iTool.Cloud.Database.ServiceProvider;
using iTool.Common.Options;

using J2N.Collections.Generic;

using Orleans;
using Orleans.Runtime;
using Orleans.Runtime.Placement;
using System;
using System.Data.SqlClient;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace iTool.Cloud.Database.DistributedFilePlacementStrategyFixedProvider
{
    public class DistributedFileProvider : IPlacementDirector
    {
        IGrainFactory iGrainFactory;
        public DistributedFileProvider(IGrainFactory iGrainFactory) 
        {
            this.iGrainFactory = iGrainFactory;
        }


        public async Task<SiloAddress> OnAddActivation(PlacementStrategy strategy, PlacementTarget target, IPlacementContext context)
        {
            Dictionary<SiloAddress, Task<int>> results = new Dictionary<SiloAddress, Task<int>>();

            try
            {
                // ip:port@hash
                //172.24.96.1:20000@401551942
                string fileID = target.GrainIdentity.PrimaryKeyString; // tableName

                // 如果已经指定路由，则直接激活
                if (fileID.IndexOf('/') > -1)
                {
                    return SiloAddress.FromParsableString(fileID.Split('/')[0]);
                }


                var siloAddresses = context.GetCompatibleSilos(target);

                foreach (var item in siloAddresses)
                {
                    var service = this.iGrainFactory.GetGrain<iFileExistsService>(string.Format("{0}/{1}", item.ToParsableString(), fileID));
                    results.Add(item, service.IsExistsAsync());
                }

                await Task.WhenAll(results.Values);

                SiloAddress[] targetHosts = results.Where(item => item.Value.Result > -1).Select(item => item.Key).ToArray();
                int index = 0;
                if (targetHosts.Any())
                {
                    index = new Random().Next(targetHosts.Length - 1);
                    //if (false)
                    {
                        SiloAddress[] syncTargetHosts = results.Where(item => item.Value.Result == -1).Select(item => item.Key).ToArray();
                        // 这是同步文件动作
                        if (syncTargetHosts.Any())
                        {
                            await Task.WhenAll(syncTargetHosts.Select(item => this.iGrainFactory.GetGrain<iFileExistsService>(string.Format("{0}/{1}", item.ToParsableString(), fileID)).AcceptNotificationSyncFileDataAsync(targetHosts.First().ToParsableString())));
                        }
                    }
                }
                else
                {
                    // 都没有 就随机调一个
                    index = new Random().Next(siloAddresses.Count - 1);
                    targetHosts = siloAddresses.ToArray();
                }

                return targetHosts[index];
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
                throw ex;
            }
        }
    }
}
